home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Sample Code / AOCE Sample Code / PowerTalk Access Modules / Sample PMSAM / PMSAM Framework / RoboSamSlot / SlotThread.cp < prev    next >
Encoding:
Text File  |  1995-07-28  |  5.6 KB  |  259 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        SlotThread.cp
  3.  
  4.     Contains:    xxx put contents here xxx
  5.  
  6.     Written by:    Tim Harnett
  7.  
  8.     Copyright:    © 1994 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.         <17>     2/14/95    TMH        replace GetEWorldSlot and GetHFSSlot with GetExternalSlot
  13.         <16>     2/14/95    TMH        added IsLetterInTheEventQueue
  14.         <15>     2/10/95    TMH        change wireless to HFS
  15.         <14>      2/7/95    TMH        stop sending if disconnect recieved
  16.         <13>      2/6/95    TMH        implemented bRecieveAfterSendNow
  17.         <12>     1/13/95    TMH        removed EWorldSlot and HFS slot dependency
  18.         <11>     1/11/95    TMH        tweak to generalize framework
  19.         <10>    12/16/94    TMH        avoid sending (immediate)  letter twice
  20.          <9>    12/12/94    TMH        use of thread events
  21.          <8>    11/17/94    TMH        connect only once
  22.          <7>    11/12/94    TMH        removed reference to CommThread
  23.          <6>     11/8/94    TMH        added fIdentifierTag argument
  24.          <5>    10/11/94    TMH        CommThread integration
  25.          <4>     10/6/94    TMH        fixed bug in DoOutgoing
  26.          <3>     10/3/94    TMH        break of THFS&TEWorld from TExternalSlot
  27.          <2>     9/30/94    TMH        added DoIncoming
  28.          <1>     9/21/94    TMH        seperated from Application.cp
  29.                  9/21/94    TMH        xxx put comment here xxx
  30.  
  31.     To Do:
  32. */
  33.  
  34. #ifndef __SlotThread__
  35. #include "SlotThread.h"
  36. #endif
  37.  
  38. #ifndef __UFAILURE__
  39. #include "UFailure.h"
  40. #endif
  41.  
  42. #ifndef __Debug__
  43. #include "Debug.h"
  44. #endif
  45.  
  46. #ifndef __Application__
  47. #include "Application.h"
  48. #endif
  49.  
  50. #ifndef __Globals__
  51. #include "Globals.h"
  52. #endif
  53.  
  54. #ifndef __MSAMSlot__
  55. #include "MSAMSlot.h"
  56. #endif
  57.  
  58. #ifndef __ExternalSlot__
  59. #include "ExternalSlot.h"
  60. #endif
  61.  
  62. #ifndef __ALetter__
  63. #include "ALetter.h"
  64. #endif
  65.  
  66. #ifndef __LogErrors__
  67. #include "LogErrors.h"
  68. #endif
  69.  
  70.  
  71. Boolean gRecieveAfterSendNow = false;
  72.  
  73.  
  74. //-----------------------------------------------
  75. //        T S l o t T h r e a d
  76. //-----------------------------------------------
  77.  
  78.  
  79.  
  80. //-------------------------------------------------------------------------------------
  81. TSlotThread::TSlotThread()
  82. {
  83.     fMSAMSlot = 0;
  84. }
  85.  
  86.  
  87.  
  88. //-------------------------------------------------------------------------------------
  89. void TSlotThread::ISlotThread(TMSAMSlot* slot)
  90. {
  91.     ASSERT(slot);
  92.     fMSAMSlot = slot;
  93.  
  94.     this->ICooperativeThread('slot',kDefaultThreadStackSize,kNewSuspend+kNeedEventQueue);
  95.  
  96.  
  97. }
  98.  
  99. #pragma segment SlotThread
  100. //-------------------------------------------------------------------------------------
  101. void* TSlotThread::ThreadMain()
  102. {
  103.  
  104.     while( true ) {
  105.  
  106.         FailInfo fi;
  107.         Try(fi) {
  108.  
  109.  
  110.                 //    Events are handle one at time.  If we are processing all outgoing
  111.                 //    and incoming all are done before we are back here checking for other
  112.                 //    events.  Whenever we are waiting for an event assume that we are disconnected.
  113.                 //••• deal with prioritized events
  114.                 
  115.                 
  116.             CThreadEvent* event = this->WaitNextEvent();
  117.  
  118.             TExternalSlot* xSlot = fMSAMSlot->GetExternalSlot();
  119.                 
  120.             ASSERT( xSlot );
  121.             if( xSlot == 0 )
  122.                 continue;
  123.  
  124.  
  125.  
  126.             switch( event->EventID() ) {
  127.  
  128.             case kMailEPPCContinue:
  129.             case kMailEPPCModifySlot:
  130.                 xSlot->SetConfiguration();
  131.                                                 // intentionally fall thru see if letters should be sent
  132.             case kMailEPPCMsgPending:
  133.                 
  134.                 if( !xSlot->ShouldSendWaitingLetters() ) 
  135.                     break;
  136.                     
  137.                     //    fall thru 
  138.                     
  139.             case kMailEPPCSchedule:
  140.                         
  141.                 xSlot->Connect();
  142.                 
  143.                 xSlot->SendOutgoingLetters();
  144.                 
  145.                 if( !this->HasUserInterrupted() )
  146.                     xSlot->ReceiveIncomingLetters();
  147.                 
  148.                 xSlot->Disconnect();
  149.                 
  150.                 if( this->HasUserInterrupted() )
  151.                     this->ClearUserInterrupt();
  152.                 
  153.                 break;
  154.  
  155.  
  156.             case kMailEPPCSendImmediate:
  157.                 {
  158.  
  159.                 Boolean connected = false;
  160.                 Boolean moreSendImmediates = false;
  161.                 
  162.                 do {
  163.                 
  164.                     long    letterSeqNo = event->EventData0();
  165.                     if( !fMSAMSlot->IsLetterDone(letterSeqNo) ) {        // in case the letter has already been sent.
  166.  
  167.                         if( !connected ) {        // do this only for the first letter we send.
  168.                             xSlot->Connect();
  169.                             connected = true;
  170.                         }
  171.  
  172.  
  173.                         TOutgoingALetter* outgoingLetter = new TOutgoingALetter;
  174.                         outgoingLetter->IOutgoingALetter(fMSAMSlot,letterSeqNo);
  175.                         xSlot->SendLetter(outgoingLetter);
  176.                         
  177.                         
  178.                     }
  179.                         
  180.                         //    Check the event queue for more letters to send now. We make no attempt
  181.                         //    to process events other than kMailEPPCSendImmediate. If there are no kMailEPPCSendImmediate.
  182.                         //    we disconnect. And process other events normally. With greater effort 
  183.                         //    a more intelligent approach could be implemented. But not today as this
  184.                         //    is simple and makes sense most of the time.
  185.                         
  186.                                             
  187.                     if( this->HasUserInterrupted() )
  188.                         break;
  189.                     
  190.                     
  191.                     moreSendImmediates = false;
  192.                     event = this->EventAvail();        // peek into the event queue
  193.                     if( (event != 0) && (event->EventID() == kMailEPPCSendImmediate) ) {
  194.                         event = this->GetNextEvent();    
  195.                         moreSendImmediates = true;
  196.                     }
  197.  
  198.  
  199.                  } while( moreSendImmediates );
  200.                     
  201.  
  202.  
  203.                 if( gRecieveAfterSendNow && !this->HasUserInterrupted() )
  204.                     xSlot->ReceiveIncomingLetters();
  205.  
  206.  
  207.                 xSlot->Disconnect();
  208.                     
  209.                 if( this->HasUserInterrupted() )
  210.                     this->ClearUserInterrupt();
  211.                 
  212.                 
  213.                 }
  214.                 break;
  215.             
  216.             default:
  217.                 ASSERTPRINT(false,("Unknown slot event.\n"));
  218.                 break;
  219.             };
  220.  
  221.  
  222.             fi.Success();
  223.         } else {
  224.         
  225.             LogError(fi.error,fMSAMSlot);
  226.             
  227.         }
  228.         
  229.         
  230.         
  231.     }
  232.     
  233.     return this;        
  234. }
  235.  
  236.  
  237. //-----------------------------------------------------------------------------------------------------------------------
  238. Boolean TSlotThread::IsLetterInTheEventQueue(long letterSeqNo,Boolean deleteIt)
  239. {
  240.     Boolean    isInQueue = false;
  241.     
  242.     CThreadEventIterator    iter(this);
  243.     for(CThreadEvent* threadEvent = iter.FirstEvent(); iter.More(); threadEvent = iter.NextEvent() ) {
  244.     
  245.         if( threadEvent->EventData0() == letterSeqNo ) {
  246.         
  247.             if( deleteIt ) 
  248.                 iter.FlushCurrentEvent();
  249.                 
  250.             isInQueue = true;
  251.             break;
  252.         }
  253.         
  254.     }
  255.  
  256.     return isInQueue;
  257.     
  258. }
  259.